#ifndef CONN_POOL_H
#define CONN_POOL_H

#include <memory>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>

#include "./MysqlHandler.h"

namespace DbConnPool
{
    class DbConnPool
    {
    public:
        static DbConnPool &getInstance(const std::string &confFilePath); // 需要绝对路径，std::ifstream才能打开文件
        ~DbConnPool() = default;                                         // 用智能指针管理，默认析构即可

        // OPTIMIZE: shared_ptr<>连接 -> unique_ptr<>相关改动
        std::unique_ptr<MysqlHandler, std::function<void(MysqlHandler *)>> getConn();

    private:
        explicit DbConnPool(const std::string &confFilePath);
        DbConnPool(const DbConnPool &cp) = delete;
        DbConnPool &operator=(const DbConnPool &cp) = delete;
        DbConnPool(const DbConnPool &&cp) = delete;
        DbConnPool &operator=(const DbConnPool &&cp) = delete;

        bool parseJsonConfigFile();
        void addConn();

        void produceConn();
        void recycleConn();

        // OPTIMIZE: 添加配置文件路径成员变量相关改动
        std::string confFilePath_;

        std::string ip_;
        unsigned short port_;
        std::string user_;
        std::string password_;
        std::string dbName_;

        int minSize_;
        int maxSize_;
        int timeout_;
        int maxIdleTime_;

        std::queue<std::unique_ptr<MysqlHandler>> connQueue_; // 连接池队列，从尾进从头出
        int curSize_;

        std::mutex mtx_;
        std::condition_variable cond_;
    };
} // namespace DbConnPool

#endif // CONN_POOL_H